/**
 * **************** Copyright (C) *****************
 * <p/>
 * Version       Date            Author
 * ─────────────────────────────────────
 * V1.0        2017/6/17         yellowlgx
 * <p/>
 * **************** End of Head *******************
 */
package android.support.v7.widget;

import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.skyworth.ui.newrecycleview.INewRecycleAdapter;
import com.skyworth.ui.newrecycleview.NewRecycleAdapterItem;
import com.skyworth.ui.newrecycleview.NewRecycleViewHolder;
import com.skyworth.ui.newrecycleview.OnBoundaryListener;
import com.skyworth.ui.newrecycleview.OnItemClickListener;
import com.skyworth.ui.newrecycleview.OnItemFocusChangeListener;
import com.skyworth.ui.newrecycleview.OnLoadMoreListener;

import java.util.ArrayList;
import java.util.List;


/**
 * @author : yellowlgx
 * @ClassName NewRecycleAdapter
 * @Description : TODO
 * @date : 2017/6/17 15:43
 */
public abstract class NewRecycleAdapter<T> extends RecyclerView.Adapter<NewRecycleViewHolder> implements
        INewRecycleAdapter<T>
{
    private static final String TAG = "NewRecycleAdapter";
    private List<T> mDatas = null;
    private List<NewRecycleViewHolder> mViewHolders = new ArrayList<NewRecycleViewHolder>();

    private OnItemFocusChangeListener mItemFocusChangeListener = null;
    private OnItemClickListener mItemClickListener = null;
    private OnBoundaryListener mBoundaryListener = null;
    private OnLoadMoreListener mLoadMoreListener = null;
    private ViewGroup mParent;

    /**
     * @Fields mViewTypeCount item的类型总数
     */
    private int mViewTypeCount = 1;

    /**
     * @Fields mViewType 每个item的类型，会根据每一条数据进行产生
     */
    private Object mViewType;

    private ItemTypeUtil util;

    public NewRecycleAdapter(List<T> datas, int viewTypeCount)
    {
        mDatas = datas;
        mViewTypeCount = viewTypeCount;
        util = new ItemTypeUtil();
        setHasStableIds(true);
    }

    public void refreshUI(List<T> datas)
    {
        this.mDatas = datas;
        notifyDataSetChanged();
    }

    public void setOnBoundaryListener(OnBoundaryListener listener)
    {
        mBoundaryListener = listener;
    }

    public void setOnItemFocusChangeListener(OnItemFocusChangeListener listener)
    {
        mItemFocusChangeListener = listener;
    }

    public void setOnItemClickListener(OnItemClickListener listener)
    {
        mItemClickListener = listener;
    }

    public void setOnLoadMoreListener(OnLoadMoreListener listener)
    {
        mLoadMoreListener = listener;
    }

    @Override
    public List<T> getData()
    {
        return mDatas;
    }

    @Override
    public T getItem(int position)
    {
        return mDatas != null ? mDatas.get(position) : null;
    }

    @Override
    public Object getItemType(T t)
    {
        return -1;
    }

    @Override
    public int getItemViewType(int position)
    {
        if (mDatas != null && mDatas.size() > position)
            mViewType = getItemType(mDatas.get(position));
        else
            mViewType = 0;
//        // 如果不写这个方法，会让listView更换dataList后无法刷新数据
        return util.getIntType(mViewType);
//        return (Integer) mViewType;
    }

    @Override
    public NewRecycleViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        mParent = parent;
        ViewGroup.LayoutParams params = generateLayoutParams(parent);
        NewRecycleAdapterItem<T> item = onCreateItem(mViewType);
        item.clearItem();
        View view = item.getView();
        view.setOnKeyListener(onKeyListener);
        view.setOnFocusChangeListener(focusChangeListener);
        view.setOnClickListener(clickListener);
        if (params != null)
            view.setLayoutParams(params);
        NewRecycleViewHolder holder = new NewRecycleViewHolder(view);
        mViewHolders.add(holder);
        return holder;
    }

    @Override
    public void onBindViewHolder(NewRecycleViewHolder holder, int position)
    {
//        Log.v("lgx", "onBindViewHolder position--> " + position);
//        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR1)
//            holder.setIsRecyclable(false);
        holder.setData(mDatas.get(holder.getLayoutPosition()), holder.getLayoutPosition());
//        holder.refreshUI();
    }

    public ViewGroup.LayoutParams generateLayoutParams(ViewGroup parent)
    {
        if (parent instanceof RecyclerView)
            return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup
                    .LayoutParams.WRAP_CONTENT);
        if (parent instanceof FrameLayout)
            return new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams
                    .WRAP_CONTENT);
        return null;
    }

    @Override
    public long getItemId(int position)
    {
        return position;
    }

    @Override
    public void onViewRecycled(NewRecycleViewHolder holder)
    {
        holder.clearItem();
        mViewHolders.remove(holder);
    }

    public List<NewRecycleViewHolder> getViewHolders()
    {
        return mViewHolders;
    }

    @Override
    public int getItemCount()
    {
        return mDatas != null ? mDatas.size() : 0;
    }

    @Override
    public boolean onFailedToRecycleView(NewRecycleViewHolder holder)
    {
        return true;
    }

    @Override
    public void onViewAttachedToWindow(NewRecycleViewHolder holder)
    {
//        Log.v("lgx", "onViewAttachedToWindow  getLayoutPosition--> " + holder.getLayoutPosition());
        if (!mViewHolders.contains(holder))
            mViewHolders.add(holder);
    }

    View.OnFocusChangeListener focusChangeListener = new View.OnFocusChangeListener()
    {
        @Override
        public void onFocusChange(final View v, boolean hasFocus)
        {
            if (mItemFocusChangeListener != null)
            {
                int position = ((RecyclerView.LayoutParams) v.getLayoutParams()).getViewLayoutPosition();
                mItemFocusChangeListener.focusChange(v, position, hasFocus);
            }
            mParent.invalidate();

//            if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR1)
//            {
//                mParent.invalidate();
//            }
        }
    };

    View.OnClickListener clickListener = new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            if (mItemClickListener != null && v instanceof NewRecycleAdapterItem)
            {
                NewRecycleViewHolder holder = (NewRecycleViewHolder) ((RecyclerView.LayoutParams) v
                        .getLayoutParams()).mViewHolder;
                mItemClickListener.click(v, holder.getLayoutPosition());
            }
        }
    };

    View.OnKeyListener onKeyListener = new View.OnKeyListener()
    {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event)
        {
            if (event.getAction() == KeyEvent.ACTION_DOWN)
            {
                NewRecycleViewHolder holder = (NewRecycleViewHolder) ((RecyclerView.LayoutParams) v
                        .getLayoutParams()).mViewHolder;
                int mPosition = holder.getLayoutPosition();
                switch (keyCode)
                {
                    case KeyEvent.KEYCODE_DPAD_UP:
                        if (mLoadMoreListener != null)
                            mLoadMoreListener.onLoadPre(v, mPosition, 0);
                        if (mBoundaryListener != null)
                            return mBoundaryListener.onTopBoundary(v, mPosition);
                    case KeyEvent.KEYCODE_DPAD_DOWN:
                        if (mLoadMoreListener != null)
                            mLoadMoreListener.onLoadMore(v, mPosition, getItemCount());
                        if (mBoundaryListener != null)
                            return mBoundaryListener.onDownBoundary(v, mPosition);
                    case KeyEvent.KEYCODE_DPAD_LEFT:
                        if (mBoundaryListener != null)
                            return mBoundaryListener.onLeftBoundary(v, mPosition);
                    case KeyEvent.KEYCODE_DPAD_RIGHT:
                        if (mBoundaryListener != null)
                            return mBoundaryListener.onRightBoundary(v, mPosition);
                    case KeyEvent.KEYCODE_BUTTON_A:
                        v.callOnClick();
                        return true;

                    default:
                        if (mBoundaryListener != null)
                            return mBoundaryListener.onOtherKeyEvent(v, mPosition, keyCode);
                }
            }
            return false;
        }
    };

    class ItemTypeUtil
    {
        /**
         * [int,obj]
         * <p/>
         * int : 最终的type obj : 传入的type
         */
        private SparseArray<Object> typeSArr = new SparseArray<Object>();

        /**
         * @param type item的类型
         * @return 通过object类型的type来得到int类型的type
         */
        public int getIntType(Object type)
        {
            int index = typeSArr.indexOfValue(type);
            if (index == -1)
            {
                index = typeSArr.size();
                // 如果没用这个type，就存入这个type
                typeSArr.put(index, type);
            }
            return index;
        }
    }
}
